use super::{json, ok, Base, CBase, Client, Resp, VBase, VMap, Value, VecF};
use std::collections::HashMap;

pub struct U;

impl Base for U {}

impl CBase for U {}

impl U {
    pub async fn do_cmd(&self, para: &Value, client: &Client) -> Resp {
        let data = para.ckobj()?;
        let sub = data.ck_i64("sub")?;
        let (tab, obj) = self.get_tab_pu(&data);

        let cmd = self.data_pu_cmd(data, &tab, &obj)?;
        let body = client.timedb(&cmd, "get").await?;

        let (da_total, da_reject) = self.get_data_pu(&body, sub, &tab, &obj)?;

        let group = da_total.len();

        let (mut line, cl) = self.reject_pu(&da_total, &da_reject);

        // 上下限
        let mut ucl = VecF::new();
        let mut lcl = VecF::new();

        // 总样本数：所有子组容量数值的求和
        let mut total = 0;
        // 总不良数：所有子组不良数值的求和
        let mut worse = 0;
        // 最大子组容量：子组容量输入值里值最大的那个值
        let mut max_val = 0;
        // 最小子组容量：子组容量输入值里值最小的那个值
        let mut min_val = 0;

        for i in 0..group {
            let t = da_total[i] as u64;
            let w = da_reject[i] as u64;
            total += t;
            worse += w;

            if max_val == 0 && min_val == 0 {
                max_val = t;
                min_val = t;
            } else {
                max_val = max_val.max(t);
                min_val = min_val.min(t);
            }

            let d = cl / (t as f64);
            let d = d.sqrt();

            ucl.push(cl + 3.0 * d);
            lcl.push((cl - 3.0 * d).max(0.0));
        }

        let mut ret = HashMap::new();

        if let Some((res_n, sta)) = self.do_normal(&mut line, sub, total as i64, None) {
            ret.insert("n", res_n);
            ret.insert("sta", json!(sta));

            if let Some(cpk) = self.calc_cpk(data, &sta) {
                ret.insert("cpk", json!(cpk));
            }
        }

        ret.insert("total", json!(total));

        let d = json!({
            "maindata": line,   // 每组的不良数值,p图中绘制线
            "data_t": da_total, // 每组的总数
            "data_r": da_reject,// 每组的不良
            "cl": cl,           // 平均不良率
            "ucl": ucl,         // 上下限
            "lcl": lcl,
            "group": group as f64,                      // 子组数：数据输入表里的子组编号的数量
            "cl_val": (total as f64) / (group as f64),  // 平均子组容量：子组容量之和除以子组数
            "max_val": max_val as f64,                  // 最大子组容量：子组容量输入值里值最大的那个值
            "min_val": min_val as f64,                  // 最小子组容量：子组容量输入值里值最小的那个值
            "reject": worse as f64,                     // 总缺陷数：所有子组不良数值的求和
            "avg_reg": (worse as f64) / (total as f64), // 平均缺陷数
        });

        ret.insert("d", d);

        ok!(ret)
    }
}
